<?php

/**
 * 大数据算法
 * Created by NetBeans IDE.
 * User: Jahem
 * Date: 2018/09/29
 * Time: 09:47
 */

namespace Algorithm;

class Algorithm {

    /**
     * 欧几里得距离
     * @param 二维Array $datalist 抽样样本
     * @param 二维Array->key $person1 抽样样本里的对象
     * @param 二维Array->key $person2 抽样样本里的对象
     * @return float 越近1，两个抽样样本里的对象越相同
     * PS:https://baike.baidu.com/item/%E6%AC%A7%E5%87%A0%E9%87%8C%E5%BE%97%E5%BA%A6%E9%87%8F/1274107?fromtitle=%E6%AC%A7%E5%87%A0%E9%87%8C%E5%BE%97%E8%B7%9D%E7%A6%BB&fromid=2701459&fr=aladdin
     */
    public static function sim_distance($datalist, $person1, $person2) {
        $si = [];
        foreach ($datalist[$person1] as $moviename => $grade) {
            if (array_key_exists($moviename, $datalist[$person2])) {
                $si[$moviename] = 1;
            }
        }
        if (empty($si)) {
            return 0;
        }
        $powers = 0;
        foreach ($si as $moviename => $val) {
            $powers += pow(($datalist[$person1][$moviename] - $datalist[$person2][$moviename]), 2); //两者影评分数相减的平方值  
        }
        return 1 / (1 + sqrt($powers));
    }
    /**
     * 皮尔逊相关系数
     * @param 二维Array $datalist 抽样样本
     * @param 二维Array->key $person1 抽样样本里的对象
     * @param 二维Array->key $person2 抽样样本里的对象
     * @return float 越近1，两个抽样样本里的对象越相同
     * PS:https://baike.baidu.com/item/%E7%9A%AE%E5%B0%94%E9%80%8A%E7%9B%B8%E5%85%B3%E7%B3%BB%E6%95%B0/12712835?fr=aladdin
     */
    public static function sim_person($datalist, $person1, $person2) {
        $si = array();
        foreach ($datalist[$person1] as $moviename => $grade) {
            if (array_key_exists($moviename, $datalist[$person2])) {
                $si[$moviename] = 1;
            }
        }
        if (empty($si)) {
            return 1;
        }
        $n = count($si);
        $sum1 = $sum1Sq = $sum2 = $sum2Sq = $pSum = 0;
        foreach ($si as $moviename => $val) {
            $sum1 += $datalist[$person1][$moviename];   //个人分数累加  
            $sum1Sq += pow($datalist[$person1][$moviename], 2); //个人分数平方的累加  
            $sum2 += $datalist[$person2][$moviename];
            $sum2Sq += pow($datalist[$person2][$moviename], 2);
            $pSum += ( $datalist[$person1][$moviename] * $datalist[$person2][$moviename]); //两人之乘积  
        }
        $num = $pSum - ( $sum1 * $sum2 / $n); // 正常情况下，我怎么都觉得这是1吧？  
        $den = sqrt(( $sum1Sq - pow($sum1, 2) / $n) * ( $sum2Sq - pow($sum2, 2) / $n));
        if ($den == 0) {
            return 0;
        }
        return ($num / $den );
    }

}
